package GUILayer;

import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

import CtrLayer.SupplierCtr;
import CtrLayer.ProductCtr;
import ModelLayer.Clothing;
import ModelLayer.Equipment;
import ModelLayer.GunReplicas;
import ModelLayer.Product;
import ModelLayer.Supplier;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

public class ProductUI extends JPanel {
	private JTextField txtProdId;
	private JComboBox<String> cbTypeOfProd;
	private JTextField txtName;
	private JTextField txtPurchasePrice;
	private JTextField txtSalesPrice;
	private JTextField txtRentPrice;
	private JTextField txtCountryOfOrigin;
	private JTextField txtMinStock;
	private JTextField txtStockAmount;
	private JComboBox<String> cbSuppliers;
	private JTextField txtExtra_1;
	private JTextField txtExtra_2;
	private JTextField txtFilter;
	private JButton btnView;
	private JButton btnCreate;
	private JButton btnUpdate;
	private JButton btnDelete;
	private JButton btnClear;
	private JScrollPane ProductScrollPane;
	private JTable ProductTable;
	
	private ProductTableModel prodTableModel;
	private JLabel lblExtra_1;
	private JLabel lblExtra_2;
	
	private SupplierCtr supCtr;
	private ProductCtr prodCtr;

	public ProductUI() {
		supCtr = new SupplierCtr();
		prodCtr = new ProductCtr();
		setLayout(null);

		JPanel panelEdit = new JPanel();
		panelEdit.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Product", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panelEdit.setBounds(10, 13, 346, 471);
		add(panelEdit);
		panelEdit.setLayout(null);

		JLabel lblProdId = new JLabel("Id");
		lblProdId.setHorizontalAlignment(SwingConstants.RIGHT);
		lblProdId.setBounds(10, 21, 85, 14);
		panelEdit.add(lblProdId);

		txtProdId = new JTextField();
		txtProdId.setBounds(104, 17, 134, 22);
		panelEdit.add(txtProdId);
		txtProdId.setEditable(false);
		txtProdId.setColumns(10);

		JLabel lblTypeOfProd = new JLabel("Type Of Product");
		lblTypeOfProd.setHorizontalAlignment(SwingConstants.RIGHT);
		lblTypeOfProd.setBounds(10, 53, 85, 14);
		panelEdit.add(lblTypeOfProd);
		
		cbTypeOfProd = new JComboBox<String>();
		cbTypeOfProd.setModel(new DefaultComboBoxModel<String>(new String[] {"Clothing", "Equipment", "GunReplicas"}));
		cbTypeOfProd.setSelectedIndex(-1);
		cbTypeOfProd.setBounds(104, 50, 134, 20);
		cbTypeOfProd.addActionListener (new ActionListener () {
		    public void actionPerformed(ActionEvent e) {
		        changeSelectedType();
		    }
		});
		panelEdit.add(cbTypeOfProd);

		JLabel lblName = new JLabel("Name");
		lblName.setHorizontalAlignment(SwingConstants.RIGHT);
		lblName.setBounds(10, 85, 85, 14);
		panelEdit.add(lblName);

		txtName = new JTextField();
		txtName.setBounds(104, 81, 134, 22);
		panelEdit.add(txtName);
		txtName.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtName.setColumns(10);

		JLabel lblPurchasePrice = new JLabel("Purchase Price");
		lblPurchasePrice.setHorizontalAlignment(SwingConstants.RIGHT);
		lblPurchasePrice.setBounds(10, 118, 85, 14);
		panelEdit.add(lblPurchasePrice);

		txtPurchasePrice = new JTextField();
		txtPurchasePrice.setBounds(104, 114, 134, 22);
		panelEdit.add(txtPurchasePrice);
		txtPurchasePrice.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtPurchasePrice.setColumns(10);

		JLabel lblSalesPrice = new JLabel("Sales Price");
		lblSalesPrice.setHorizontalAlignment(SwingConstants.RIGHT);
		lblSalesPrice.setBounds(10, 151, 85, 14);
		panelEdit.add(lblSalesPrice);

		txtSalesPrice = new JTextField();
		txtSalesPrice.setBounds(104, 147, 134, 22);
		panelEdit.add(txtSalesPrice);
		txtSalesPrice.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtSalesPrice.setColumns(10);

		JLabel lblRentPrice = new JLabel("Rent Price");
		lblRentPrice.setHorizontalAlignment(SwingConstants.RIGHT);
		lblRentPrice.setBounds(10, 184, 85, 14);
		panelEdit.add(lblRentPrice);

		txtRentPrice = new JTextField();
		txtRentPrice.setBounds(104, 180, 134, 22);
		panelEdit.add(txtRentPrice);
		txtRentPrice.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtRentPrice.setColumns(10);
		
		JLabel lblCountryOfOrigin = new JLabel("County Of Origin");
		lblCountryOfOrigin.setHorizontalAlignment(SwingConstants.RIGHT);
		lblCountryOfOrigin.setBounds(10, 216, 85, 14);
		panelEdit.add(lblCountryOfOrigin);
		
		txtCountryOfOrigin = new JTextField();
		txtCountryOfOrigin.setBounds(104, 213, 134, 20);
		panelEdit.add(txtCountryOfOrigin);
		txtCountryOfOrigin.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtCountryOfOrigin.setColumns(10);
		
		JLabel lblMinimumStock = new JLabel("Minimum Stock");
		lblMinimumStock.setHorizontalAlignment(SwingConstants.RIGHT);
		lblMinimumStock.setBounds(10, 244, 85, 14);
		panelEdit.add(lblMinimumStock);
		
		txtMinStock = new JTextField();
		txtMinStock.setBounds(104, 241, 134, 20);
		panelEdit.add(txtMinStock);
		txtMinStock.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtMinStock.setColumns(10);
		
		JLabel lblStockAmount = new JLabel("Stock Amount");
		lblStockAmount.setHorizontalAlignment(SwingConstants.RIGHT);
		lblStockAmount.setBounds(10, 275, 85, 14);
		panelEdit.add(lblStockAmount);
		
		txtStockAmount = new JTextField();
		txtStockAmount.setBounds(104, 272, 134, 20);
		panelEdit.add(txtStockAmount);
		txtStockAmount.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				enableClear();
			}
		});
		txtStockAmount.setColumns(10);
		
		JLabel lblSupplier = new JLabel("Supplier");
		lblSupplier.setHorizontalAlignment(SwingConstants.RIGHT);
		lblSupplier.setBounds(10, 306, 85, 14);
		panelEdit.add(lblSupplier);
		
		cbSuppliers = new JComboBox<String>();
		cbSuppliers.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				getSuppliers();
			}
		});
		cbSuppliers.setBounds(104, 303, 134, 20);
		panelEdit.add(cbSuppliers);
		
		txtExtra_1 = new JTextField();
		txtExtra_1.setBounds(104, 334, 134, 20);
		panelEdit.add(txtExtra_1);
		txtExtra_1.setColumns(10);
		
		txtExtra_2 = new JTextField();
		txtExtra_2.setBounds(104, 365, 134, 20);
		panelEdit.add(txtExtra_2);
		txtExtra_2.setColumns(10);
		
		lblExtra_1 = new JLabel("Extra 1");
		lblExtra_1.setHorizontalAlignment(SwingConstants.RIGHT);
		lblExtra_1.setBounds(10, 337, 85, 14);
		panelEdit.add(lblExtra_1);
		
		lblExtra_2 = new JLabel("Extra 2");
		lblExtra_2.setHorizontalAlignment(SwingConstants.RIGHT);
		lblExtra_2.setBounds(10, 368, 85, 14);
		panelEdit.add(lblExtra_2);
		
		btnCreate = new JButton("Create");
		btnCreate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				createProduct();
			}
		});
		btnCreate.setBounds(248, 17, 86, 23);
		panelEdit.add(btnCreate);

		btnUpdate = new JButton("Update");
		btnUpdate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				updateProduct();
			}
		});
		btnUpdate.setBounds(248, 49, 86, 23);
		panelEdit.add(btnUpdate);

		btnDelete = new JButton("Delete");
		btnDelete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				deleteProduct();
			}
		});
		btnDelete.setBounds(248, 81, 86, 23);
		panelEdit.add(btnDelete);

		btnClear = new JButton("Clear");
		btnClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				clearInputs();
				enableClear();
			}
		});
		btnClear.setBounds(248, 114, 86, 23);
		btnClear.setEnabled(false);
		panelEdit.add(btnClear);
		
		/**
		 * Second page
		 */

		JPanel panelTableModel = new JPanel();
		panelTableModel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Products", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panelTableModel.setBounds(371, 13, 612, 343);
		add(panelTableModel);
		panelTableModel.setLayout(null);

		ProductScrollPane = new JScrollPane();
		ProductScrollPane.setBounds(12, 13, 590, 284);
		ProductTable = new JTable();
		prodTableModel = new ProductTableModel();
		prodTableModel.populateList();
		ProductTable.setModel(prodTableModel);
		ProductScrollPane.setViewportView(ProductTable);
		panelTableModel.add(ProductScrollPane);

		JLabel lblFilter = new JLabel("Filter:");
		lblFilter.setHorizontalAlignment(SwingConstants.RIGHT);
		lblFilter.setBounds(12, 314, 85, 14);
		panelTableModel.add(lblFilter);
		
		txtFilter = new JTextField();
		txtFilter.setBounds(107, 310, 116, 22);
		panelTableModel.add(txtFilter);
		txtFilter.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				filterProducts();
			}
		});
		txtFilter.setColumns(10);

		btnView = new JButton("View");
		btnView.setBounds(505, 309, 97, 25);
		btnView.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				viewProduct(ProductTable.getSelectedRow());
			}
		});
		panelTableModel.add(btnView);
	}

	protected void getSuppliers() {
		if(cbSuppliers.getSelectedIndex() == -1)
		{
			cbSuppliers.setModel(new DefaultComboBoxModel<String>());
			for(String s : supCtr.listSupplierNames())
			{
				cbSuppliers.addItem(s);
			}
			
		}
		if(cbSuppliers.getModel().getSize() != supCtr.listSupplierNames().size())
		{
			cbSuppliers.setModel(new DefaultComboBoxModel<String>());
			for(String s : supCtr.listSupplierNames())
			{
				cbSuppliers.addItem(s);
			}
		}
	}

	protected void changeSelectedType() {
		if(cbTypeOfProd.getSelectedItem().equals("Clothing"))
		{
			lblExtra_1.setText("Size");
			lblExtra_2.setText("Colour");
		}
		if(cbTypeOfProd.getSelectedItem().equals("Equipment"))
		{
			lblExtra_1.setText("Type");
			lblExtra_2.setText("Description");
		}
		if(cbTypeOfProd.getSelectedItem().equals("GunReplicas"))
		{
			lblExtra_1.setText("Fabric");
			lblExtra_2.setText("Calibre");
		}
		
	}

	protected void createProduct() {
		if(isAllInputsFilled(false))
		{
			Supplier sup = supCtr.findSup((String) cbSuppliers.getSelectedItem());
			if(cbTypeOfProd.getSelectedItem().equals("Clothing"))
			{
				prodCtr.insertCloth(txtName.getText(), Double.parseDouble(txtPurchasePrice.getText()), Double.parseDouble(txtSalesPrice.getText()), Double.parseDouble(txtRentPrice.getText()), txtCountryOfOrigin.getText(), Integer.parseInt(txtMinStock.getText()), Integer.parseInt(txtStockAmount.getText()), sup, txtExtra_1.getText(), txtExtra_2.getText());
			}
			if(cbTypeOfProd.getSelectedItem().equals("Equipment"))
			{
				prodCtr.insertEquip(txtName.getText(), Double.parseDouble(txtPurchasePrice.getText()), Double.parseDouble(txtSalesPrice.getText()), Double.parseDouble(txtRentPrice.getText()), txtCountryOfOrigin.getText(), Integer.parseInt(txtMinStock.getText()), Integer.parseInt(txtStockAmount.getText()), sup, txtExtra_1.getText(), txtExtra_2.getText());
			}
			if(cbTypeOfProd.getSelectedItem().equals("GunReplicas"))
			{
				prodCtr.insertGunRep(txtName.getText(), Double.parseDouble(txtPurchasePrice.getText()), Double.parseDouble(txtSalesPrice.getText()), Double.parseDouble(txtRentPrice.getText()), txtCountryOfOrigin.getText(), Integer.parseInt(txtMinStock.getText()), Integer.parseInt(txtStockAmount.getText()), sup, txtExtra_1.getText(), txtExtra_2.getText());
			}
			prodTableModel.populateList();
			clearInputs();
		}	
	}
	protected void updateProduct() {
		if(isAllInputsFilled(true))
		{
			Supplier sup = supCtr.findSup((String) cbSuppliers.getSelectedItem());
			if(cbTypeOfProd.getSelectedItem().equals("Clothing"))
			{
				prodCtr.updateCloth(Integer.parseInt(txtProdId.getText()),txtName.getText(), Double.parseDouble(txtPurchasePrice.getText()), Double.parseDouble(txtSalesPrice.getText()), Double.parseDouble(txtRentPrice.getText()), txtCountryOfOrigin.getText(), Integer.parseInt(txtMinStock.getText()), Integer.parseInt(txtStockAmount.getText()), sup, txtExtra_1.getText(), txtExtra_2.getText());
			}
			if(cbTypeOfProd.getSelectedItem().equals("Equipment"))
			{
				prodCtr.updateEquip(Integer.parseInt(txtProdId.getText()),txtName.getText(), Double.parseDouble(txtPurchasePrice.getText()), Double.parseDouble(txtSalesPrice.getText()), Double.parseDouble(txtRentPrice.getText()), txtCountryOfOrigin.getText(), Integer.parseInt(txtMinStock.getText()), Integer.parseInt(txtStockAmount.getText()), sup, txtExtra_1.getText(), txtExtra_2.getText());
			}
			if(cbTypeOfProd.getSelectedItem().equals("GunReplicas"))
			{
				prodCtr.updateGunRep(Integer.parseInt(txtProdId.getText()),txtName.getText(), Double.parseDouble(txtPurchasePrice.getText()), Double.parseDouble(txtSalesPrice.getText()), Double.parseDouble(txtRentPrice.getText()), txtCountryOfOrigin.getText(), Integer.parseInt(txtMinStock.getText()), Integer.parseInt(txtStockAmount.getText()), sup, txtExtra_1.getText(), txtExtra_2.getText());
			}
			prodTableModel.populateList();
			clearInputs();
		}
		
	}
	
	protected void deleteProduct() {
		if(!txtProdId.getText().isEmpty())
		{
			prodCtr.removeProd(Integer.parseInt(txtProdId.getText()));
		}
		prodTableModel.populateList();
		clearInputs();
	}

	protected void viewProduct(int selectedRow) {
		if(selectedRow > -1)
		{
			Product prod = prodCtr.findProd((int) ProductTable.getModel().getValueAt(selectedRow, 0));
			txtProdId.setText(String.valueOf(prod.getProductId()));
			txtName.setText(prod.getName());
			txtPurchasePrice.setText(String.valueOf(prod.getPurchasePrice()));
			txtSalesPrice.setText(String.valueOf(prod.getSalesPrice()));
			txtRentPrice.setText(String.valueOf(prod.getRentPrice()));
			txtCountryOfOrigin.setText(prod.getCountryOfOrigin());
			txtMinStock.setText(String.valueOf(prod.getMinStock()));
			txtStockAmount.setText(String.valueOf(prod.getStockAmount()));
			getSuppliers();
			cbSuppliers.setSelectedItem(prod.getSupplier().getName());
			
			if(prod instanceof Clothing)
			{
				cbTypeOfProd.setSelectedItem("Clothing");
				Clothing c = (Clothing) prod;
				txtExtra_1.setText(c.getSize());
				txtExtra_2.setText(c.getColour());
			}
			if(prod instanceof Equipment)
			{
				cbTypeOfProd.setSelectedItem("Equipment");
				Equipment e = (Equipment) prod;
				txtExtra_1.setText(e.getType());
				txtExtra_2.setText(e.getDescription());
			}		
			if(prod instanceof GunReplicas)
			{
				cbTypeOfProd.setSelectedItem("GunReplicas");
				GunReplicas g = (GunReplicas) prod;
				txtExtra_1.setText(g.getFabric());
				txtExtra_2.setText(g.getCalibre());
			}
			cbTypeOfProd.setEnabled(false);
			changeSelectedType();
		}
	}

	protected void filterProducts() {
		prodTableModel.populateList(txtFilter.getText());

	}

	/**
	 * Clear inputs, all are empty.
	 */
	protected void clearInputs() {
		txtProdId.setText("");
		txtName.setText("");
		txtPurchasePrice.setText("");
		txtSalesPrice.setText("");
		txtRentPrice.setText("");
		txtCountryOfOrigin.setText("");
		txtMinStock.setText("");
		txtStockAmount.setText("");
		txtExtra_1.setText("");
		txtExtra_2.setText("");
		btnClear.setEnabled(false);
		cbTypeOfProd.setEnabled(true);
		cbSuppliers.setSelectedIndex(-1);
		btnCreate.transferFocus();
	}

	/**
	 * Enable of clearing, checks if all inputs are empty.
	 */
	protected void enableClear() {
		btnClear.setEnabled(anyInputFilled());
	}
	/*
	 * Helper function, this is used to avoid code reuse
	 */
	protected boolean anyInputFilled()
	{
		boolean isFilled = false;
		// || is or logic
		if(!txtName.getText().isEmpty() || !txtPurchasePrice.getText().isEmpty() ||
				!txtSalesPrice.getText().isEmpty() || !txtRentPrice.getText().isEmpty() ||
				!txtCountryOfOrigin.getText().isEmpty() || !txtMinStock.getText().isEmpty() ||
				!txtStockAmount.getText().isEmpty() || !txtExtra_1.getText().isEmpty() ||
				!txtExtra_2.getText().isEmpty())
		{
			isFilled = true;
		}
		return isFilled;
	}
	protected boolean isAllInputsFilled(boolean checkId)
	{
		boolean allFilled = false;
		// && is and logic
		if(!txtName.getText().isEmpty() && !txtPurchasePrice.getText().isEmpty() &&
				!txtSalesPrice.getText().isEmpty() && !txtRentPrice.getText().isEmpty() &&
				!txtCountryOfOrigin.getText().isEmpty() && !txtMinStock.getText().isEmpty() &&
				!txtStockAmount.getText().isEmpty() && !txtExtra_1.getText().isEmpty() &&
				!txtExtra_2.getText().isEmpty())
		{
			if(checkId && txtProdId.getText().isEmpty())
			{
				allFilled = false;
			}
			else{
				allFilled = true;
			}
		}
		
		return allFilled;
	}
}